iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 24
0
Software Development

Ruby 研究 30 天系列 第 24

Day 23 - 引數與參數 下篇

  • 分享至 

  • xImage
  •  

引數與參數

承昨天的話題,今天來把剩下的引數帶入方式介紹完。

  • Variable Argument
    全名稱作 variable-length argument list ,也就是長度可變的引數組,用來帶入任意數量(從0到無窮大),有 single splatdouble splat 兩種。

single splat:

在參數前加上 * 符號,而引數帶入的方式是把引數們放進一個陣列裡:

def testArgs(arg_1, *more)
  more
end

testArgs(1, "apple", [1, 2, 3], key: :value)
# 印出  ["apple", [1, 2, 3], {:key=>:value}]

既然是放進陣列,那理所當然可以用陣列的方法加以應用:

def say_hello(my_name, *others_names)
  others_names.each {|name| puts "Hi, I'm #{my_name}. Greeting to you, #{name}!!"}
end

say_hello("Karen", "Thor", "Stark", "Morgan", "Happy", "Parker")
# 印出以下內容
# Hi, I'm Karen. Greeting to you, Thor!!
# Hi, I'm Karen. Greeting to you, Stark!!
# Hi, I'm Karen. Greeting to you, Morgan!!
# Hi, I'm Karen. Greeting to you, Happy!!
# Hi, I'm Karen. Greeting to you, Parker!!

可以發現這樣一個簡易的打招呼系統,未來如果有添加新的客人要也不須更動程式碼結構。

double splat:

在參數前加上 ** 符號,可以用來搭配 keyword argument ,可以想像引數們是被傳進 Hash 中。

def testArgs(arg_1, *more, **rest)
 p arg_1, more, rest
end

testArgs(1, 2, 3, 4, 5, a: 1, b: 2, c: 3) 
# 印出 1 [2, 3, 4, 5] {:a=>1, :b=>2, :c=>3}

我們來試試各種引數亂入:

def args_fightting(a, b = 42, *c, **d)
  [a, b, c, d]
end

args_fightting(1) # 得到 [1, 42, [], {}]
# 可以發現 Standard Argument 的優先度最高

args_fightting(1, 2, 3, 4) # 得到 [1, 2, [3, 4], {}]
# 滿足 Standard Argument 後,有多餘的會先分給 Optional Argument
# 不是 Keyword Argument 的引數都會被放進 single splat 

args_fightting(1, 2, 3, d: 4, e: 5)  # 得到 [1, 2, [3], {:d=>4, :e=>5}]
# Keyword Argument 的引數會被放進 double plat

args_fightting(c: 3, d: 4) # 得到 [{:c=>3, :d=>4}, 42, [], {}]
# 有種 Keyword Argument 被搶走的感覺,但其實是被判定成一個省略花括號 {} 的 hash 作為Standard Argument

以上程式碼中,有兩個重點:

  1. 當有多個引數的帶入時,需將參數依照 standard -> optional -> variable -> keyword 這樣的順序排列,否則會出現引數或語法錯誤。
  2. 呈上,因優先度的關係,當你符合一個單位,像是最後的例子是 一個 省略花括號 hash ,就會被 standard 抓走。
  • Catch-All Argument
    單用一個 * 代表著把所有的引數抓取,但抓取後不能自己操作,那實務上怎麼應用呢?
class Breakfast
  def nutrition(vitamins, minerals)
    puts vitamins
    puts minerals
  end
end

class Bacon < Breakfast
  def nutrition(*)
    super
    puts "I also make you fat"
  end
end
bacon = Bacon.new
bacon.nutrition("B6", "iron")

# 印出以下內容
# B6
# iron
# I also make you fat

這裡有個看起來有點酷的字眼 super ,我們明天來分享吧!

此文同步刊登於CJ-Han的網站


上一篇
Day 22 - 引數與參數 上篇
下一篇
Day 24 - Super
系列文
Ruby 研究 30 天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言